package zhang.oauth_resource.ResourceToken;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.AccessTokenConverter;
import org.springframework.security.oauth2.provider.token.DefaultAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.ResourceServerTokenServices;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.Map;

/**
 * http://localhost:9000/oauth/check_token
 */
@Service
@ConfigurationProperties("zhang")
public class ResourceTokenService implements ResourceServerTokenServices {

    private RestTemplate restTemplate;
    private AccessTokenConverter tokenConverter = new DefaultAccessTokenConverter();
    private String checkTokenEndpointUrl;
    private static final String tokenName = "token";

    public ResourceTokenService() {
        restTemplate = new RestTemplate();
        ((RestTemplate) restTemplate).setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            // Ignore 400
            public void handleError(ClientHttpResponse response) throws IOException {
                if (response.getRawStatusCode() != 400) {
                    super.handleError(response);
                }
            }
        });
    }

    @Override
    public OAuth2Authentication loadAuthentication(String accessToken) throws AuthenticationException, InvalidTokenException {


        MultiValueMap<String, String> formData = new LinkedMultiValueMap<String, String>();
        formData.add(tokenName, accessToken);
        Map map = postForMap(checkTokenEndpointUrl,formData);

        if (map.containsKey("error")) {

            throw new InvalidTokenException(accessToken);
        }

        return tokenConverter.extractAuthentication(map);
    }

    public Map<String,Object> postForMap(String url,Map maps){


        return restTemplate.postForObject(url,maps,Map.class);
    }

    @Override
    public OAuth2AccessToken readAccessToken(String accessToken) {

          return null;
    }

    public String getCheckTokenEndpointUrl() {
        return checkTokenEndpointUrl;
    }

    public void setCheckTokenEndpointUrl(String checkTokenEndpointUrl) {
        this.checkTokenEndpointUrl = checkTokenEndpointUrl;
    }


}
